package com.sdksoft.readcard

import android.content.Intent
import android.media.MediaPlayer
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.csht.bean.EPassportData
import com.csht.bean.FingerPrintData
import com.csht.bean.IdCardData
import com.csht.enums.ReadCardType
import com.csht.enums.StatusCode
import com.csht.listener.InitListener
import com.csht.listener.ReadCardListener
import com.sdksoft.readcard.databinding.ActivitySamMultiBinding
import com.sdksoft.readcard.databinding.PortSettingBinding
import com.csht.utils.BytesUtils
import com.csht.utils.HHTipUtils
import org.json.JSONObject
import java.util.Locale

class SamMultiActivity : BaseInitActivity(), ReadCardListener {

    private val TAG = "SamMultiActivity"

    private var player: MediaPlayer? = null

    private lateinit var portSettingBinding: PortSettingBinding
    private lateinit var samMultiBinding: ActivitySamMultiBinding

    private var isInitOk = false

    private var myFingerPrintData: MutableList<FingerPrintData> = mutableListOf() // 指纹数据

    override fun initView() {
        super.initView()
        setTitleText("SAM多合一读卡")
        portSettingBinding = PortSettingBinding.inflate(layoutInflater)
        samMultiBinding = ActivitySamMultiBinding.inflate(layoutInflater)
        baseActivityBinding.llContent.apply {
            addView(samMultiBinding.root, 0)
            addView(portSettingBinding.root, 0)
        }
        samMultiBinding.apply {
            btnPassport.text = "开始读护照/通行证"
            btnPassport.setOnClickListener {
                ivHead.setImageResource(0)
                startPassportRead()
            }
            btnStartRead.text = "开始读身份证/银行卡"
            btnStartRead.setOnClickListener {
                ivHead.setImageResource(0)
                startIDCardRead()
            }
            tvMsg.text = ""
            btnFingerPrint.setOnClickListener {
                // 核验指纹
                if (myFingerPrintData.isNotEmpty()) {
                    // 验证第一枚指纹
                    val fingerPrintData = myFingerPrintData[0]
                    HHTipUtils.getInstance()
                        .showToast(this@SamMultiActivity, "请按压" + fingerPrintData.msg)
                    // 指纹核验超时时间 最小3秒
                    readCardManager.checkFP(fingerPrintData.code, 5000)
                } else {
                    HHTipUtils.getInstance().showToast(this@SamMultiActivity, "请先读证件指纹")
                }
            }
        }
        portSettingBinding.apply {
            save.setOnClickListener {
                if (isInitOk) {
                    readCardManager.readCardStop()
                    readCardManager.readCardReleaseDestory()
                    isInitOk = false
                }
                initSDK()
            }
        }
        player = MediaPlayer.create(applicationContext, R.raw.success)
        initSDK()
    }

    /**
     * 初始化SDK
     */
    private fun initSDK() {
        portSettingBinding.apply {
            readSettingBuilder
                .buildReadCardType(ReadCardType.SAM_202_USB)
                // 设置串口号、波特率（串口读卡时需要设置）
                .buildSerialPort(
                    deviceFilePath.text.toString().trim(),
                    baudrate.text.toString().trim().toInt()
                )
        }
        readCardManager.readCardInit(object : InitListener {
            override fun onResponse(code: Int, msg: String) {
                when (code) {
                    StatusCode.ININ_ING.code -> {
                        Log.d(TAG, "初始化中. $msg")
                    }

                    StatusCode.ININ_OK.code -> {
                        isInitOk = true
                        runOnUiThread {
                            HHTipUtils.getInstance().showToast(this@SamMultiActivity, "初始化成功")
                            samMultiBinding.tvMsg.apply {
                                text = "----初始化成功---->"
                                append("\ncode：$code")
                                append("\nmsg：$msg")
                            }
                        }
                    }

                    else -> {
                        isInitOk = false
                        runOnUiThread {
                            HHTipUtils.getInstance().showToast(this@SamMultiActivity, "初始化失败")
                            samMultiBinding.tvMsg.apply {
                                text = "----初始化失败---->"
                                append("\ncode：$code")
                                append("\nmsg：$msg")
                            }
                        }
                    }
                }
            }
        })
    }

    private fun startIDCardRead() {
        if (isInitOk.not()) {
            HHTipUtils.getInstance().showToast(this@SamMultiActivity, "没有初始化成功")
            return
        }
        myFingerPrintData = arrayListOf()
        samMultiBinding.tvMsg.text = "请放置身份证/银行卡"
        readCardManager.readCardStart(this)
    }

    private fun startPassportRead() {
        if (isInitOk.not()) {
            HHTipUtils.getInstance().showToast(this@SamMultiActivity, "没有初始化成功")
            return
        }
        myFingerPrintData = arrayListOf()
        samMultiBinding.apply {
            val documentNumberStr = documentNumber.text.toString().trim().toUpperCase(Locale.ROOT)
            val dateOfBirthStr = dateOfBirth.text.toString().trim()
            val dateOfExpiryStr = dateOfExpiry.text.toString().trim()
            if (documentNumberStr.isEmpty() || dateOfBirthStr.isEmpty() || dateOfExpiryStr.isEmpty()) {
                HHTipUtils.getInstance().showToast(this@SamMultiActivity, "请完整填写参数")
                return@apply
            }
            samMultiBinding.tvMsg.text = "请放置对应护照"
            // 开始读取护照
            readCardManager.readPassportStart(
                Intent(), documentNumberStr, dateOfBirthStr, dateOfExpiryStr, this@SamMultiActivity
            )
        }
    }

    fun appendLog(log: String) {
        samMultiBinding.apply {
            tvMsg.append(log)
        }
    }

    override fun onReadCardState(type: Int, msg: String?) {
        when (type) {
            StatusCode.READCARD_FAILE.code, StatusCode.M1_READ_FAIL.code -> {
                HHTipUtils.getInstance().dismissProgressDialog()
                HHTipUtils.getInstance().showToast(this, "type:$type\n$msg")
                samMultiBinding.tvMsg.text =
                    "\n----------------------------\nstatus: $type  ，msg:$msg"
            }

            StatusCode.READCARD_SUCCESS.code -> {
                HHTipUtils.getInstance().dismissProgressDialog()
                HHTipUtils.getInstance().showToast(this, "type:$type\n$msg")
            }

            StatusCode.FIND_CARD_START.code -> {
                if (!HHTipUtils.getInstance().progressDialogIsShowing()) {
                    HHTipUtils.getInstance().showProgressDialog(this, "正在寻卡", false)
                }
            }

            StatusCode.FIND_CARD_SUCCESS.code -> {
                if (!HHTipUtils.getInstance().progressDialogIsShowing()) {
                    HHTipUtils.getInstance().showProgressDialog(this, "正在读取,请勿移动", false)
                } else {
                    HHTipUtils.getInstance().setProgressDialogMsg("正在读取,请勿移动")
                }
            }

            StatusCode.CHECK_FP_START.code -> { // 指纹核验开始
                if (!HHTipUtils.getInstance().progressDialogIsShowing()) {
                    HHTipUtils.getInstance().showProgressDialog(this, "开始核验$msg", false)
                }
            }
        }
    }

    override fun onAPDUFindCardSuccess(resultBytes: ByteArray?) {
        super.onAPDUFindCardSuccess(resultBytes)
        HHTipUtils.getInstance().dismissProgressDialog()
        // resultBytes  卡类型（ 1字节）+ UID长度（1字节）+ UID + 复位号长度（1字节）+ 复位号
        //卡类型
        //01： 卡片类型ISO14443-A
        //02： 卡片类型ISO14443-B
        //04： IC门禁卡\M1
        appendLog("\n----接收到寻卡成功---->")
        when (resultBytes?.get(0)) {
            0x01.toByte() -> {
                appendLog("\n卡片类型：ISO14443-A")

                // APDU 操作 A卡
//                val apdu = byteArrayOf(0x00, 0x36, 0x00, 0x00, 0x08)
//                val data = readCardManager.sendAPDUWithReturn(apdu, 1000)
//                if (data != null) {
//                    // 读取到数据
//                }
            }

            0x02.toByte() -> {
                appendLog("\n卡片类型：ISO14443-B")

                // APDU 操作 B卡
            }

            0x04.toByte() -> {
                appendLog("\n卡片类型：IC门禁卡、M1")
                val lenUID = resultBytes[1].toInt() and 0xFF
                appendLog(
                    "\n卡号：${
                        BytesUtils.bytesToHexString(
                            resultBytes.copyOfRange(
                                2,
                                2 + lenUID
                            )
                        )
                    }"
                )

                // 示例  操作 M1卡
                /**
                 * @param type  1: 读M1卡的块数据 2：写块数据 3：扇区数据块加密
                 * ==================================================================================================
                 * 当 type == 1 时：
                 * byteArray 格式 ：<扇区号(1 byte)> + <秘钥类型(1 byte)> + <秘钥数据(6 byte)> + <块号(1 byte)>
                 *
                 * ==================================================================================================
                 * 当 type == 2 时：
                 * byteArray 格式 ：<扇区号(1 byte)> + <秘钥类型(1 byte)> + <秘钥数据(6 byte)> + <块号(1 byte)> + <块数据 16 byte 每包>
                 *
                 * ==================================================================================================
                 * 当 type == 3 时：
                 * byteArray 格式 ：<扇区号(1 byte)> + <秘钥类型(1 byte)> + <旧 秘钥数据(6 byte)> + <新 秘钥数据(6 byte)>
                 *
                 * 秘钥类型:  0x00为 A密钥  0x01为 B密钥
                 */
                // 示例
                // 读取M1卡 01 扇区， 02 块的数据，秘钥类型为A密钥，秘钥数据为 全 FF
                val byteArray = byteArrayOf(
                    0x01.toByte(), // 扇区号
                    0x00.toByte(), // 秘钥类型
                    0xFF.toByte(), // 秘钥数据 6 字节
                    0xFF.toByte(),
                    0xFF.toByte(),
                    0xFF.toByte(),
                    0xFF.toByte(),
                    0xFF.toByte(),
                    0x01.toByte()  // 块号
                )
                readCardManager.M1Card(1, byteArray, this, null)
            }
        }
    }

    override fun onReadICCardSuccess(icNumber: String?, type: Int) {
        player?.start()
        HHTipUtils.getInstance().dismissProgressDialog()
        samMultiBinding.ivHead.setImageResource(0)
        samMultiBinding.tvMsg.apply {
            text = "----读卡成功---->"
            append("\n卡类型：$type")
            append("\n-------------------------")
            if (type == StatusCode.CARD_BANK.code) { // 银行卡
                try {
                    icNumber?.let {
                        val jsonObject = JSONObject(icNumber)
                        append("\n卡号：${jsonObject.optString("cardNumber", "")}")
                        append("\n凭证号：${jsonObject.optString("certificateNum", "")}")
                        append("\n有效日期：${jsonObject.optString("validityTime", "")}")
                        val transDetail = jsonObject.getJSONArray("transDetail")
                        for (i in 0 until transDetail.length()) {
                            append("\n-------------------------")
                            val transDetailItem = transDetail.getJSONObject(i)
                            append("\n交易日期：${transDetailItem.optString("transactionDate", "")}")
                            append("\n交易时间：${transDetailItem.optString("transactionTime", "")}")
                            append(
                                "\n授权金额：${
                                    transDetailItem.optString(
                                        "authorizedAmount",
                                        ""
                                    )
                                }"
                            )
                            append("\n其它金额：${transDetailItem.optString("otherAmount", "")}")
                            append("\n终端国家代码：${transDetailItem.optString("countryCode", "")}")
                            append(
                                "\n交易货币代码：${
                                    transDetailItem.optString(
                                        "currencyCode",
                                        ""
                                    )
                                }"
                            )
                            append("\n商户名称：${transDetailItem.optString("merchantName", "")}")
                            append("\n交易类型：${transDetailItem.optString("transactionType", "")}")
                            append("\n应用交易计数器：${transDetailItem.optString("ATC", "")}")
                        }
                    }
                } catch (e: Exception) {
                }
            } else {
                append("\n卡号：$icNumber")
            }
        }
    }

    override fun onReadIDCardSuccess(bean: IdCardData?) {
        player?.start()
        HHTipUtils.getInstance().dismissProgressDialog()
        bean?.apply {
            bitmap?.let { bitmap ->
                samMultiBinding.ivHead.setImageBitmap(bitmap)
            }
            samMultiBinding.tvMsg.apply {
                text = "读取成功："
                when (type) {
                    StatusCode.CARD_IDCARD_FOREIGN.code, StatusCode.CARD_IDCARD_FOREIGN_OLD.code -> { // 外国永久居住证
                        append("\n中文姓名：")
                        append(nameChinese)
                        append("\n英文姓名：")
                        append(nameEnglish)
                        append("\n性别：")
                        append(sex)
                        append("\n生日：")
                        append(birthday)
                        append("\n国籍：")
                        append(nationlity)
                        append("\n证件号码：")
                        append(bean.id)
                        append("\n有效期限：")
                        append(startDate)
                        append(" - ")
                        append(endDate)
                    }

                    StatusCode.CARD_IDCARD.code -> { // 中国居民身份证
                        append("\n姓名：")
                        append(name)
                        append("\n性别：")
                        append(sex)
                        append("\n民族：")
                        append(nation)
                        append("\n生日：")
                        append(birthday)
                        append("\n住址：")
                        append(address)
                        append("\n证件号码：")
                        append(bean.id)
                        append("\n签发机关：")
                        append(bean.issue)
                        append("\n有效期限：")
                        append(startDate)
                        append(" - ")
                        append(endDate)
                    }
                }
                // 有有效指位信息，可以进行指纹核验。指位信息 每7个字节表示一个指纹指位。
                // 需要核验哪一个指位，则将该指位信息的 code 字节传递给指纹核验函数。
                if (fingerPrintData.isNotEmpty()) {
                    myFingerPrintData = fingerPrintData
                    append("\n\n获取到指位信息：")
                    fingerPrintData.forEach {
                        append("${it.msg},")
                    }
                }
                append("\n\n证件指纹信息长度：${fingerPrint.size}")
                append("\n\n耗时：$distime ms")
            }
        }
    }

    override fun onCheckFP(isSuccess: Boolean, msg: String?, data: ByteArray?) {
        super.onCheckFP(isSuccess, msg, data)
        HHTipUtils.getInstance().dismissProgressDialog()
        samMultiBinding.tvMsg.apply {
            text = "指纹核验：------->"
            append("\n\n状态：${isSuccess}")
            append("\n\nmsg：$msg")
            append("\n\ndata：${BytesUtils.bytesToHexString(data)}")
            if (isSuccess) {
                // 获取两个指位信息。每个指纹5字节（1字节指位信息 + 4字节相似度）。
                val fingerPrintData1 = data?.copyOfRange(88, 93) ?: ByteArray(5)
                val fingerPrintData2 = data?.copyOfRange(93, 98) ?: ByteArray(5)
                Log.e("HH", "fingerPrintData1: ${BytesUtils.bytesToHexString(fingerPrintData1)}")
                Log.e("HH", "fingerPrintData2: ${BytesUtils.bytesToHexString(fingerPrintData2)}")
                myFingerPrintData.forEach {
                    if (it.code == fingerPrintData1[0]) {
                        append("\n\n指位1：${it.msg}")
                        append(
                            "\n\n相似度1：${
                                BytesUtils.byte4ToFloat(
                                    fingerPrintData1.copyOfRange(
                                        1,
                                        5
                                    ).reversedArray()
                                )
                            }"
                        )
                    } else if (it.code == fingerPrintData2[0]) {
                        append("\n\n指位2：${it.msg}")
                        append(
                            "\n\n相似度2：${
                                BytesUtils.byte4ToFloat(
                                    fingerPrintData2.copyOfRange(
                                        1,
                                        5
                                    ).reversedArray()
                                )
                            }"
                        )
                    }
                }
            }
        }
    }

    override fun onReadPassportSuccess(bean: EPassportData?) {
        super.onReadPassportSuccess(bean)
//        samMultiBinding.apply {
//            documentNumber.setText("")
//            dateOfBirth.setText("")
//            dateOfExpiry.setText("")
//        }
        player?.start()
        HHTipUtils.getInstance().dismissProgressDialog()
        bean?.apply {
            samMultiBinding.tvMsg.apply {
                text = "姓名："
                append(nameOfHolder)
                append(" / $primaryIdentifier $secondaryIdentifier")
                append("\n性别：")
                append(if (gender.startsWith("M")) "男" else "女")
                append(" / $gender")
                append("\n生日：")
                append(dateOfBirth)
                append("\n国家码：")
                append(nationality)
                append("\n有效期：")
                append(dateOfExpiry)
                append("\n护照号码：")
                append(documentNumber)
                append("\n个人号码：")
                append(personNumber)
                append("\n护照机读码：")
                append(mrz)
                append("\npassiveAuth：")
                append(passiveAuth.toString())
                append("\n\n耗时：$duration ms")
            }
            if (headBitmap == null) {
                samMultiBinding.ivHead.setImageResource(0)
            } else {
                headBitmap?.let {
                    samMultiBinding.ivHead.setImageBitmap(headBitmap)
                }
            }
        }
    }

    override fun onResultM1Data(data: ByteArray?) {
        super.onResultM1Data(data)
        HHTipUtils.getInstance().dismissProgressDialog()
        data?.let {
            appendLog("\n----------------------------\nM1卡: \n${String(data, Charsets.UTF_8)}")
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        player?.release()
        HHTipUtils.getInstance().dismissProgressDialog()
        mainHandler.removeCallbacksAndMessages(null)
        readCardManager.readCardStop()
        readCardManager.readCardReleaseDestory()
    }
}